﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using MyVoteMVC.Data.Repositories;
//using MyVoteMVC.Domain;
using System.Reflection;
using System.Collections.Specialized;
using System.Configuration;
//using MyVoteMVC.Common;

namespace MyVoteMVC.Common
{
    /// <summary>
    /// 类工厂
    /// </summary>
    public static class Factory
    {
        static Factory() {

        }

        /// <summary>
        /// 类型注册初始化
        /// </summary>
        /// <param name="factoryInitializer"></param>
        public static void Initailize(IFactoryInitializer factoryInitializer)
        {
            if (factoryInitializer == null)
            {
                throw new ArgumentNullException("需要提供一个初始化接口IFactoryInitializer的实现");
            }

            foreach (FactoryConfigSection section in factoryInitializer.GetSectionIterator())
            {
                foreach (TypeConfigurationElement type in section.Types)
                    RegisterTypeMapping(Type.GetType(type.name, true), Type.GetType(type.mapto, true));
            }
        }
        
        private static Dictionary<Type, Type> classTypes = new Dictionary<Type, Type>();

        /// <summary>
        /// 获取相关类型TEntity的一个实例
        /// </summary>
        /// <typeparam name="TEntity">类型</typeparam>
        /// <param name="args">类型初始化需要的参数</param>
        /// <returns>类型实例</returns>
        public static TEntity GetInstance<TEntity>(params object[] args) where TEntity : class
        {
            if (classTypes.ContainsKey(typeof(TEntity)))
            {
                Type internalFactory = typeof(InternalFactory<,>);

                internalFactory = internalFactory.MakeGenericType(typeof(TEntity), classTypes[typeof(TEntity)]);

                MethodInfo method = internalFactory.GetMethod("Create", BindingFlags.Static | BindingFlags.NonPublic);

                return (TEntity)method.Invoke(

                    internalFactory, new object[] { args });
            }
            else
            {
                throw new Exception("类型: " + typeof(TEntity)
                    + " 未注册");
            }
        }

        /// <summary>
        /// 类型注册
        /// </summary>
        /// <typeparam name="I">Key值类型</typeparam>
        /// <typeparam name="C">Value值类型</typeparam>
        public static void RegisterTypeMapping<I, C>()
        {
            if (!classTypes.ContainsKey(typeof(I)))
            {
                classTypes.Add(typeof(I), typeof(C));
            }
        }

        /// <summary>
        /// 类型注册
        /// </summary>
        /// <param name="I">Key值类型</param>
        /// <param name="C">Value值类型</param>
        public static void RegisterTypeMapping(Type I, Type C)
        {
            if (!classTypes.ContainsKey(I))
            {
                classTypes.Add(I, C);
            }
        }
    }
}
